package com.niit.chat.websocket;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.niit.chat.service.MessageSessionService;
import com.niit.chat.vo.MessageSessionVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * WebSocket服务端点
 */
@Slf4j
@Component
@ServerEndpoint("/websocket/chat/{userId}")
public class ChatWebSocketServer {

    // 用静态变量保存所有WebSocket连接
    private static final Map<Long, Session> ONLINE_SESSIONS = new ConcurrentHashMap<>();
    
    // 使用静态变量保存服务实例，因为WebSocket是多例的
    private static MessageSessionService messageSessionService;
    
    private static ObjectMapper objectMapper;
    
    @Autowired
    public void setMessageSessionService(MessageSessionService messageSessionService) {
        ChatWebSocketServer.messageSessionService = messageSessionService;
    }
    
    @Autowired
    public void setObjectMapper(ObjectMapper objectMapper) {
        ChatWebSocketServer.objectMapper = objectMapper;
    }

    /**
     * 连接建立成功调用的方法
     */
    @OnOpen
    public void onOpen(Session session, @PathParam("userId") Long userId) {
        log.info("WebSocket连接建立: userId={}", userId);
        ONLINE_SESSIONS.put(userId, session);
        
        // 连接成功后，立即发送最新的会话列表
        sendSessionList(userId);
    }

    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose(@PathParam("userId") Long userId) {
        log.info("WebSocket连接关闭: userId={}", userId);
        ONLINE_SESSIONS.remove(userId);
    }

    /**
     * 收到客户端消息后调用的方法
     */
    @OnMessage
    public void onMessage(String message, @PathParam("userId") Long userId) {
        log.info("收到WebSocket消息: userId={}, message={}", userId, message);
        // 这里可以处理客户端发来的消息，如果需要的话
    }

    /**
     * 发生错误时调用的方法
     */
    @OnError
    public void onError(Session session, Throwable error) {
        log.error("WebSocket发生错误", error);
    }

    /**
     * 向指定用户发送会话列表
     */
    public static void sendSessionList(Long userId) {
        Session session = ONLINE_SESSIONS.get(userId);
        if (session != null && session.isOpen()) {
            try {
                List<MessageSessionVO> sessions = messageSessionService.getUserSessions(userId);
                String message = objectMapper.writeValueAsString(sessions);
                session.getBasicRemote().sendText(message);
            } catch (IOException e) {
                log.error("发送会话列表失败", e);
            }
        }
    }

    /**
     * 当有新消息时，通知相关用户更新会话列表
     */
    public static void notifySessionUpdate(Long senderId, Long receiverId) {
        // 通知发送者更新会话列表
        sendSessionList(senderId);
        
        // 通知接收者更新会话列表
        sendSessionList(receiverId);
    }
}